package com.xiaoxu.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaoxu.auth.mapper.SysMenuMapper;
import com.xiaoxu.auth.service.SysMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaoxu.auth.service.SysRoleMenuService;
import com.xiaoxu.auth.utils.MenuHelper;
import com.xiaoxu.common.exception.XiaoXuException;
import com.xiaoxu.model.system.SysMenu;
import com.xiaoxu.model.system.SysRoleMenu;
import com.xiaoxu.vo.system.AssginMenuVo;
import com.xiaoxu.vo.system.MetaVo;
import com.xiaoxu.vo.system.RouterVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单表 服务实现类
 * </p>
 *
 * @author xiaoxu
 * @since 2024-04-15
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    @Autowired
    private SysMenuMapper sysMenuMapper;
    @Override
    public List<SysMenu> findNodes() {

        //1.查询所有的菜单数据
        List<SysMenu> sysMenuList = baseMapper.selectList(null);

        //2.根据所有的菜单id查找子菜单数据

        //构建树形数据
        List<SysMenu> result = MenuHelper.buildTree(sysMenuList);


        //
        return result;
    }
    //删除菜单
    @Override
    public void removeMenuById(Long id) {
    //判断当前菜单是否有子菜单?

        //1.查询当前菜单是否有子菜单
        LambdaQueryWrapper<SysMenu> wrapper =new LambdaQueryWrapper<>();
        //eq就是equals
        wrapper.eq(SysMenu::getParentId,id);
        // count > 0 代表存在子菜单
        Integer i = baseMapper.selectCount(wrapper);

        if (i>0){
            throw new XiaoXuException(201,"包含子菜单不能删除");
        }

        //2.删除当前菜单
        baseMapper.deleteById(id);

    }
        //查询所有的菜单和角色分配的菜单
    @Override
    public List<SysMenu> findMenuByRoleId(Long roleId) {
        // 1.查询所有的菜单 --添加条件status =1
        LambdaQueryWrapper<SysMenu> wrapperSysMenu =new LambdaQueryWrapper<>();

        wrapperSysMenu.eq(SysMenu::getStatus,1);
        //所有的菜单列表
        List<SysMenu> allSysMenuList = baseMapper.selectList(wrapperSysMenu);

        //2.根据roleId查询所有的对应 菜单id MenuList
        LambdaQueryWrapper<SysRoleMenu> wrapperSysRoleMenu =new LambdaQueryWrapper<>();

        wrapperSysRoleMenu.eq(SysRoleMenu::getRoleId,roleId);

        List<SysRoleMenu> sysRoleMenuList = sysRoleMenuService.list(wrapperSysRoleMenu);

        //将sysRoleMenuList的menuId 遍历成一个集合
        List<Long> meunIdList = sysRoleMenuList.stream().map(ids -> ids.getMenuId()).collect(Collectors.toList());
        // 拿着菜单id 和所有的菜单集合的id进行比较 相同就封装
        allSysMenuList.stream().forEach(menu ->{
            if (meunIdList.contains(menu.getId())){
                menu.setSelect(true);
            }else {
                menu.setSelect(false);
            }
        });
        //4 返回树形列表
        List<SysMenu> sysMenuList = MenuHelper.buildTree(allSysMenuList);

        return  sysMenuList;
    }
    //
 // 为角色分配菜单
    @Override
    public void doAssign(AssginMenuVo assginMenuVo) {
        // 根据角色id 删除菜单角色表的 菜单id
        LambdaQueryWrapper<SysRoleMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRoleMenu::getRoleId,assginMenuVo.getRoleId());

        sysRoleMenuService.remove(wrapper);


        // 2.参数里面获取菜单角色表 新的菜单id列表,进行遍历,把每一个id数据添加到菜单角色表
        List<Long> menuIdList = assginMenuVo.getMenuIdList();

        for (Long menuId : menuIdList) {
            if (StringUtils.isEmpty(menuIdList)){
                continue;//跳出本次循环
            }
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            //设置当前表的role_id 以及 当前的menuId
            sysRoleMenu.setMenuId(menuId);
            sysRoleMenu.setRoleId(assginMenuVo.getRoleId());
            sysRoleMenuService.save(sysRoleMenu);
        }
    }
    //动态构建路由结构显示动态数据
    @Override
    public List<RouterVo> findUserMenuLisyByUserId(Long userId) {
        //超级管理员admin账号id为：1
        List<SysMenu> sysMenuList = null;
        if (userId.longValue() == 1) {
            sysMenuList = this.list(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getStatus, 1).orderByAsc(SysMenu::getSortValue));
        } else {
            sysMenuList = sysMenuMapper.findListByUserId(userId);
        }
        //构建树形数据
        List<SysMenu> sysMenuTreeList = MenuHelper.buildTree(sysMenuList);

        List<RouterVo> routerVoList = this.buildMenus(sysMenuTreeList);
        return routerVoList;
    }

    private List<RouterVo> buildMenus(List<SysMenu> menus) {
        List<RouterVo> routers = new LinkedList<RouterVo>();
        for (SysMenu menu : menus) {
            RouterVo router = new RouterVo();
            router.setHidden(false);
            router.setAlwaysShow(false);
            router.setPath(getRouterPath(menu));
            router.setComponent(menu.getComponent());
            router.setMeta(new MetaVo(menu.getName(), menu.getIcon()));
            List<SysMenu> children = menu.getChildren();
            //如果当前是菜单，需将按钮对应的路由加载出来，如：“角色授权”按钮对应的路由在“系统管理”下面
            if(menu.getType().intValue() == 1) {
                List<SysMenu> hiddenMenuList = children.stream().
                        filter(item -> !StringUtils.isEmpty(item.getComponent())).
                        collect(Collectors.toList());
                for (SysMenu hiddenMenu : hiddenMenuList) {
                    RouterVo hiddenRouter = new RouterVo();
                    hiddenRouter.setHidden(true);
                    hiddenRouter.setAlwaysShow(false);
                    hiddenRouter.setPath(getRouterPath(hiddenMenu));
                    hiddenRouter.setComponent(hiddenMenu.getComponent());
                    hiddenRouter.setMeta(new MetaVo(hiddenMenu.getName(), hiddenMenu.getIcon()));
                    routers.add(hiddenRouter);
                }
            } else {
                if (!CollectionUtils.isEmpty(children)) {
                    if(children.size() > 0) {
                        router.setAlwaysShow(true);
                    }
                    router.setChildren(buildMenus(children));
                }
            }
            routers.add(router);
        }
        return routers;
    }

    public String getRouterPath(SysMenu menu) {
        String routerPath = "/" + menu.getPath();
        if(menu.getParentId().intValue() != 0) {
            routerPath = menu.getPath();
        }
        return routerPath;
    }
    //获取到操作按钮 对应数据的 perms  btn.sysUser.list .....
    @Override
    public List<String> findPermsByUserId(Long userId) {
        //超级管理员admin账号id为：1
        List<SysMenu> sysMenuList = null;
        if (userId.longValue() == 1) {
            sysMenuList = this.list(new LambdaQueryWrapper<SysMenu>()
                    .eq(SysMenu::getStatus, 1));
        } else {
            sysMenuList = sysMenuMapper.findListByUserId(userId);
        }
        List<String> permsList = sysMenuList.stream().
                filter(item -> item.getType() == 2)
                .map(item -> item.getPerms()).collect(Collectors.toList());
        return permsList;
    }
}
